#pragma once

#include <base.h>
#include <compl/candy.h>

/* 对控制流进行初始化和结束操作进行组合定义 */

/* 裸机下 */
/* c0: sysinit - coreinit - ... - corefin - fin */
/* c_: coreinit - ... - corefin - fin */
/* 操作系统内 */
/* t0: sysinit - thinit - ... - thfin - fin */
/* t_: thinit - ... - thfin - fin */

/* 采用接口形式复合方式好吗? 好处是一旦声明了函数没加进来会告警 */
// static void sys_init(void);
// MAY_UNUSED static void sys_fin(void);
// static void cflow_init(void);
// MAY_UNUSED static void cflow_fin(void);

/* 用于最终连接的空函数层 */
SAI void __omega_sysinit(void){}
SAI void __omega_sysfin(void){}
SAI void __omega_cflowinit(void){}
SAI void __omega_cflowfin(void){}


// #define __DECL_INITFIN(name, type)				\
// /* 必须对init函数进行连接, 未连接会被告警 */			\
// SAI void MCAT(name, _, type, _must_be_connected) (void);	\
// SAI void MCAT(_, name, _, type) (void);				\
// SAI void MCAT(name, _, type) (void) {  MCAT(_, name, _, type) (); MCAT(name, _, type, _must_be_connected) ();}	\
// SAI void MCAT(_, name, _, type) (void)
#define __DECL_INITFIN(name, type)				\
/* 必须对init函数进行连接, 未连接会被告警 */			\
SAI void name##_##type##_must_be_connected (void);		\
SIN void _##name##_##type (void);				\
SIN void name##_##type (void) {  _##name##_##type (); name##_##type##_must_be_connected ();}	\
SIN void _##name##_##type (void)



#define SYSINIT_FUNC(name)		__DECL_INITFIN(name, sysinit)
#define CFLOWINIT_FUNC(name)		__DECL_INITFIN(name, cflowinit)
#define SYSFIN_FUNC(name)		__DECL_INITFIN(name, sysfin)
#define CFLOWFIN_FUNC(name)		__DECL_INITFIN(name, cflowfin)



#define __CONNECTED_FUNC(type, f1)	f1##_##type##_must_be_connected
/* 系统初始化*/
#define __INITFIN_COMPOSE(type, f1, f2)	\
	SAI void __CONNECTED_FUNC(type, f1) (void) { f2##_##type (); }


#define __SYSINIT_COMPOSE(f1, f2)	__INITFIN_COMPOSE(sysinit, f1, f2)

/* 控制流初始化复合*/
#define __CFLOWINIT_COMPOSE(f1, f2)	__INITFIN_COMPOSE(cflowinit, f1, f2)

/* 控制流终结复合 */
#define __CFLOWFIN_COMPOSE(f1, f2)	__INITFIN_COMPOSE(cflowfin, f1, f2)
/* 系统终结复合 */
#define __SYSFIN_COMPOSE(f1, f2)	__INITFIN_COMPOSE(sysfin, f1, f2)

#define DEF_SYSINIT(...)						\
	MAPL(__SYSINIT_COMPOSE, GEN_PAIRLIST(__VA_ARGS__, __omega))	\
	static void sys_init(){ EXPAND(DEFER(__MCAT) (HD(__VA_ARGS__, __omega), _sysinit()) ); }

#define DEF_CFLOWINIT(...)						\
	MAPL(__CFLOWINIT_COMPOSE, GEN_PAIRLIST(__VA_ARGS__, __omega))	\
	static void cflow_init(){ EXPAND(DEFER(__MCAT) (HD(__VA_ARGS__, __omega), _cflowinit()) ); }

#define DEF_CFLOWFIN(...)						\
	MAPL(__CFLOWFIN_COMPOSE, GEN_PAIRLIST(__VA_ARGS__, __omega))	\
	MAY_UNUSED static void cflow_fin(){ EXPAND(DEFER(__MCAT) (HD(__VA_ARGS__, __omega), _cflowfin()) ); }

#define DEF_SYSFIN(...)							\
	MAPL(__SYSFIN_COMPOSE, GEN_PAIRLIST(__VA_ARGS__, __omega))	\
	MAY_UNUSED static void sys_fin(){ EXPAND(DEFER(__MCAT) (HD(__VA_ARGS__, __omega), _sysfin()) ); }
/* 复合成几个函数还是一套CEFF接口? */

/* 这两个可以复合吧? */
